/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
 * Generated on: 2020/2/06
 * Function description: adaptation header file related to the PCIe main chip
 */

#ifndef PCIE_CORE_H
#define PCIE_CORE_H
#include "pcie_chip.h"
#include "pcie_reset.h"

#define PERI_CRG37                     (0x00D4)
#define PERI_CRG37_PCIE0_SRST_REQ      (1U << PCIE_BIT_0)
#define PERI_CRG37_PCIE0_RST_REQ       (1U << PCIE_BIT_1)
#define PERI_CRG37_X2X_PCIE0_SRST_REQ  (1U << PCIE_BIT_2)
#define PERI_CRG37_X2X_PCIES_SRST_REQ  (1U << PCIE_BIT_6)
#define PERI_CRG37_PCIE0_CKEN          (1U << PCIE_BIT_8)
#define PERI_CRG37_PCIE_PHY_CKEN       (1U << PCIE_BIT_10)
#define PERI_CRG37_X2X_PCIES_CKEN      (1U << PCIE_BIT_11)
#define PERI_CRG37_PCIE_CLK_SEL        (1U << PCIE_BIT_16)
#define PERI_CRG37_PCIE_SLOT0_SRST_REQ (1U << PCIE_BIT_24)
#define PERI_CRG37_PCIE_SLOT_CKEN      (1U << PCIE_BIT_26)

#define PCIE_CFG_BUS(busnr)            ((busnr & 0xff) << 20)
#define PCIE_CFG_DEV(devfn)            ((devfn) << 12)
#define PCIE_CFG_REG(reg)              ((reg & 0xffc)) /* set dword align */

/* 1152 pcie_iatu controller reg 1 */
#define PCIE0_IATU2_REGION_CTRL_REG1_1152 (0x0)
#define PCIE1_IATU1_REGION_CTRL_REG1_1152 (0x0)
#define PCIE2_IATU1_REGION_CTRL_REG1_1152 (0x0)

/* pcie_iatu controller reg */
#define PCIE0_IATU0_LOWER_BASE_REG (0x50000000)
#define PCIE0_IATU1_LOWER_BASE_REG (0x40000000)
#define PCIE0_IATU2_LOWER_BASE_REG (0x50100000)
#define PCIE1_IATU0_LOWER_BASE_REG (0x68000000)
#define PCIE1_IATU1_LOWER_BASE_REG (0x58a00000)
#define PCIE1_IATU2_LOWER_BASE_REG (0x58000000)
#define PCIE0_IATU2_EXTLSW_LOWER_BASE_REG (0x4fe00000)

#define PCIE0_IATU0_LIMITE_REG   (0x500FFFFF)
#define PCIE0_IATU1_LIMITE_REG   (0x409FFFFF)
#define PCIE0_IATU2_LIMITE_REG   (0x57FFFFFF)
#define PCIE1_IATU0_LIMITE_REG   (0x6FFFFFFF)
#define PCIE1_IATU1_LIMITE_REG   (0x58a000ff)
#define PCIE1_IATU2_LIMITE_REG   (0x589FFFFF)
#define PCIE0_IATU_EXTLSW_LIMIT_MEM_ONE   (0x4fdfffff)
#define PCIE0_IATU_EXTLSW_LIMIT_MEM_TWO   (0x4fffffff)

/* pcie link status */
#define PCIE_OLD_BASE_CFG_SIZE   (0x1000)
#define PCIE_OLD_MEM_SIZE        (0x1000000)
#define PCIE_LINK_STAT0_5182T    (0x200)

/* pcie link status */
#define PCIE0_LINK_STAT_5115     (0x18)
#define PCIE1_LINK_STAT_5115     (0x28)
#define PCIE0_2D0_LINK_STAT_5115 (0x38)
#define PCIE1_2D0_LINK_STAT_5115 (0x3C)

#define PCIE_LINK_STAT0_5116     (0x100)
#define PCIE_LINK_STAT1_5116     (0x110)

#define PCIEX_LINK_UP 5

/* SMI */
#define MAX_MSI_IRQS             (32)

#define PCIE_CFG_HDR1            (0x004)
#define PCIE_CFG_HDR15           (0x03c)
#define PCIE_MSI_CAP0            (0x050)
#define PCIE_MSI_ADDRL           (0x054)
#define PCIE_MSI_ADDR_LO         (0x820)
#define PCIE_MSI_ADDR_HI         (0x824)
#define PCIE_MSI_INTR0_ENABLE    (0x828)
#define PCIE_MSI_INTR0_MASK      (0x82C)
#define PCIE_MSI_INTR0_STATUS    (0x830)

/* PCIE interrupt id */
#define IRQ_BASE                 (32)
#define PICE0_IRQ_INT_SHIFT_1156 (30)
#define PCIE0_IRQ_INTA           (59 + IRQ_BASE)
#define PCIE0_IRQ_INTB           (60 + IRQ_BASE)
#define PCIE0_IRQ_INTC           (61 + IRQ_BASE)
#define PCIE0_IRQ_INTD           (62 + IRQ_BASE)

#define PCIE1_IRQ_INTA           (63 + IRQ_BASE)
#define PCIE1_IRQ_INTB           (64 + IRQ_BASE)
#define PCIE1_IRQ_INTC           (65 + IRQ_BASE)
#define PCIE1_IRQ_INTD           (66 + IRQ_BASE)

#define PCIE2_IRQ_INTA           (67 + IRQ_BASE)
#define PCIE2_IRQ_INTB           (68 + IRQ_BASE)
#define PCIE2_IRQ_INTC           (69 + IRQ_BASE)
#define PCIE2_IRQ_INTD           (70 + IRQ_BASE)

#define PCIE_INTA_PIN            (1)
#define PCIE_INTB_PIN            (2)
#define PCIE_INTC_PIN            (3)
#define PCIE_INTD_PIN            (4)

/*
 * SSOC interrupt mapping table
 * supports a maximum of 96 interrupt IDs
 */
#define MAX_IRQS                 (96)
#define IRQ_OFFSET               (32)          /* interrupt id above 32 need to subtract (32) */
#define INVALID_IRQ              (0xffffffff)  /* invalid interrupt id */

#define PCIE_DEBUG_LEVEL_REG     (1)
#define PCIE_DEBUG_LEVEL_FUNC    (2)
#define PCIE_DEBUG_LEVEL_MODULE  (3)

#define PCIE_DEBUG_LEVEL         PCIE_DEBUG_LEVEL_MODULE

#define PCIE_PARA_RIGHT                  (0644)

#define PCIE_LINK_CHECK_TIMES            (1000)
#define PCIE_DATA_SIZE_1                 (1)
#define PCIE_DATA_SIZE_2                 (2)
#define PCIE_DATA_SIZE_4                 (4)
#define PCIE_DBI_WHERE_MASK              (0x3)
#define PCIE_DATA_SIZE_1_GET(val, where) ((val >> ((where & 0x3) << 3)) & 0xff)
#define PCIE_DATA_SIZE_2_GET(val, where) ((val >> ((where & 0x3) << 3)) & 0xffff)
#define PCIE_DATA_SIZE_1_CLEAR(where)    (~(0xff << ((where & 0x3) << 3)))
#define PCIE_DATA_SIZE_2_CLEAR(where)    (~(0xffff << ((where & 0x3) << 3)))
#define PCIE_DATA_SET(val, where)        (val << ((where & 0x3) << 3))

#define MEM_SPACE_SET(index) do { \
	g_pcie##index##_mem_space.start = \
		g_pcie_reg_base_addr[PCIE_INDEX_##index].mem_base_addr; \
	g_pcie##index##_mem_space.end = \
		g_pcie_reg_base_addr[PCIE_INDEX_##index].mem_base_addr + \
		g_pcie##index##_mem_space_size - 1; \
	g_pcie##index##_io_space.start = g_pcie##index##_mem_space.end + 1; \
	g_pcie##index##_io_space.end = \
		g_pcie_reg_base_addr[PCIE_INDEX_##index].mem_base_addr + \
		g_pcie##index##_base_space_size - 1; \
} while (0)

#define REQ_RES_CORRESPOND(index) do { \
	pci_add_resource_offset(&sys->resources, \
		&g_pcie##index##_io_space, sys->io_offset); \
	pci_add_resource_offset(&sys->resources, \
		&g_pcie##index##_mem_space, sys->mem_offset); \
	pcie_ctrl[PCIE_INDEX_##index].is_req_resource = true; \
} while (0)

#define CHECK_RES_SPACE(index) do { \
	ret = request_resource(&iomem_resource, &g_pcie##index##_mem_space); \
	if (ret) { \
		pr_info("Cannot request mem resource for pcie%d\n", index); \
		release_resource(&g_pcie##index##_io_space); \
	} \
} while (0)

#define _SPACE_SIZE_SET(index, type) do { \
	g_pcie##index##_mem_space_size = PCIE_MEM_SPACE_SIZE_##type; \
	g_pcie##index##_base_space_size = PCIE_BASE_ADDR_SIZE_##type; \
} while (0)

#define SPACE_SIZE_SET(index) do { \
	if (pcie_is_wifi115x_chip(PCIE_INDEX_##index)) { \
		_SPACE_SIZE_SET(index, 1152); \
	} else if (pcie_is_wifi_mxl_chip(PCIE_INDEX_##index)) { \
		_SPACE_SIZE_SET(index, MXL); \
	} else if (pcie_is_extlsw_type2125(PCIE_INDEX_##index)) { \
		if ((index) != 2) \
			g_pcie_reg_base_addr = g_pcie_reg_base_addr_lsw; \
		_SPACE_SIZE_SET(index, LSW); \
	} else { \
		_SPACE_SIZE_SET(index, COMMON); \
	} \
} while (0)

enum HI_SERDES_MODE_E {
	HI_SERDES_GPON_1G1G = 0,     /* RX:2.488Gbps	TX:1.244Gbps */
	HI_SERDES_GPON_2D5G2D5G,     /* RX:2.488Gbps	TX:2.488Gbps */
	HI_SERDES_GPON_2D5G10G,      /* RX:9.953Gbps	TX:2.488Gbps */
	HI_SERDES_GPON_10G10G,       /* RX:9.953Gbps	TX:9.953Gbps */
	HI_SERDES_GPON_3D1G12G,      /* RX:12.441Gbps	TX:3.110Gbps */
	HI_SERDES_GPON_12G12G,       /* RX:12.441Gbps	TX:12.441Gbps */
	HI_SERDES_EPON_1G1G,         /* RX:1.250Gbps	TX:1.250Gbps */
	HI_SERDES_EPON_1G10G,        /* RX:10.312Gbps	TX:1.250Gbps */
	HI_SERDES_EPON_2D5G10G,      /* RX:10.312Gbps	TX:2.500Gbps */
	HI_SERDES_EPON_10G10G,       /* RX:10.312Gbps	TX:10.312Gbps */
	HI_SERDES_GE_1G1G,           /* RX:1.250Gbps	TX:1.250Gbps */
	HI_SERDES_GE_2D5G2D5G,       /* RX:3.125Gbps	TX:3.125Gbps */
	HI_SERDES_GE_QSGMII,         /* RX:5.000Gbps	TX:5.000Gbps */
	HI_SERDES_GE_5GUSXGMII,      /* RX:5.156Gbps	TX:5.156Gbps */
	HI_SERDES_GE_5GE,            /* RX:6.250Gbps	TX:6.250Gbps */
	HI_SERDES_GE_10G10G,         /* RX:10.312Gbps	TX:10.312Gbps */
	HI_SERDES_GE_12G12G,         /* RX:12.500Gbps	TX:12.500Gbps */
	HI_SERDES_GE_12D8G12D8G,     /* RX:12.890625Gbps	TX:12.890625Gbps */
	HI_SERDES_GE_20G20G,         /* RX:20.625Gbps	TX:20.625Gbps */
	HI_SERDES_GE_25G25G,         /* RX:25.7812Gbps	TX:25.7812Gbps */
	HI_SERDES_GE_1G1G_TRACK,     /* same with HI_SERDES_GE_1G1G */
	HI_SERDES_GE_2D5G2D5G_TRACK, /* same with HI_SERDES_GE_2D5G2D5G */
	HI_SERDES_GE_10G10G_TRACK,   /* same with HI_SERDES_GE_10G10G */
	HI_SERDES_PCIE2,             /* RX:5.000Gbps  TX:5.000Gbps */
	HI_SERDES_PCIE3,             /* RX:8.000Gbps  TX:8.000Gbps */
	HI_SERDES_PCIE2_x2,          /* same with HI_FUNC_PCIE_2D0 */
	HI_SERDES_PCIE3_x2,          /* same with HI_FUNC_PCIE_3D0 */
	HI_SERDES_PCIE3_1CS,         /* same with HI_SERDES_PCIE3, separate 1cs */
	HI_SERDES_OTUL,
	HI_SERDES_OTU0,
	HI_SERDES_OTU1,
	HI_SERDES_OTU2,
	HI_SERDES_OTU2E,
	HI_SERDES_OTU2LS,
	HI_SERDES_OTU2ELS,
	HI_SERDES_MODE_NUM,
	HI_SERDES_DISABLE,           /* disable SERDES */
};

/* mapping between pcie interrupts and pins */
struct pcie_pin_irq {
	uint32_t pcie_pin;
	uint32_t pcie_irq[PCIE_INDEX_MAX];
};

struct irq_np {
	uint32_t zero;
	uint32_t irq;
	uint32_t size;
};

struct pcie_info *bus_to_info(int32_t busnr);
#endif
